package face.com.androidfacesdk;

import android.graphics.Bitmap;

import java.nio.ByteBuffer;

import face.entity.FaceModel;

/**
 * Created by mazhi on 2017/12/28.
 */

public class FaceMobile {


    /**
     * @param numThreads
     */
    public native void setNumThreads(int numThreads);

    private native int loadModel(String modelDir);  // required

    private native int loadModelv2(String modelDir,int serialType);

    /**
     * 获取android机器码
     *
     * @return
     */
    public native String getSerialNo();  // required
    public native String getSerialNov2(int serialType);  // required

    //Version2.0 下一版本开放,暂时不要使用
    private native float compare2Image(String imgFile1, String imgFile2);

    //特征提取
    private native float[] extractFeature(byte[] rgb24, int width, int height, int widthStep, int[] faceRect, float roll);

    //特征提取
    private native float[] extractFeatureForBitmap(Bitmap bmp, int width, int height, int[] faceRect, float roll);

    //释放资源
    private native void free();


    private static volatile FaceMobile instance = null;

    private boolean _inited = false;

    private FaceMobile() {
    }

    public static FaceMobile getInstance() {
        if (instance == null) {
            synchronized (FaceMobile.class) {
                if (instance == null) {
                    instance = new FaceMobile();
                }
            }
        }
        return instance;
    }







    public boolean getInited()
    {
        return _inited;
    }


    /**
     * @param modelPath 模型所在路径，deta.bin,deta.param等模型所在路径
     * @return 加载成功true, 失败false
     */
    public boolean init(String modelPath) {
        if (!_inited) {
//            if (loadModel(modelPath) > 0) {
            int load=loadModel(modelPath);
            if (load > 0) {
                _inited = true;
            }
        }
        return _inited;
    }

    /**
     * @param bmp 图片
     * @param faceModel 图片中人脸的特征点模型，通过FaceDetection中人脸检测方法获取
     * @return 人脸特征码 成功为float[]数字，失败返回null
     * @throws Exception
     */
    public float[] getFaceFeature(Bitmap bmp, FaceModel faceModel) throws Exception {
        float[] features = null;
        if (!_inited)
            throw new Exception("算法模型未加载,请调用init方法加载模型");
        if (bmp != null && faceModel != null && faceModel.rtFace != null) {
            int faceRect[] = {faceModel.rtFace.x, faceModel.rtFace.y, faceModel.rtFace.width, faceModel.rtFace.height};
            features = extractFeatureForBitmap(bmp, bmp.getWidth(), bmp.getHeight(), faceRect, faceModel.roll);
        }
        return features;
    }


    /*
 * 获取位图的RGB数据
 */
    public static byte[] getRGBByBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        int size = width * height;

        int pixels[] = new int[size];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

        byte[] data = convertColorToByte(pixels);

        return data;
    }

    /*
     * 像素数组转化为RGB数组
     */
    public static byte[] convertColorToByte(int color[]) {
        if (color == null) {
            return null;
        }

        byte[] data = new byte[color.length * 3];
        for (int i = 0; i < color.length; i++) {
            data[i * 3] = (byte) (color[i] >> 16 & 0xff);
            data[i * 3 + 1] = (byte) (color[i] >> 8 & 0xff);
            data[i * 3 + 2] = (byte) (color[i] & 0xff);
        }

        return data;

    }

    public static byte[] getPixelsBGR(Bitmap image) {
        // calculate how many bytes our image consists of
        int bytes = image.getByteCount();

        ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
        image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer

        byte[] temp = buffer.array(); // Get the underlying array containing the data.

        byte[] pixels = new byte[(temp.length / 4) * 3]; // Allocate for BGR

        // Copy pixels into place
        for (int i = 0; i < temp.length / 4; i++) {

            pixels[i * 3] = temp[i * 4 + 2];        //B
            pixels[i * 3 + 1] = temp[i * 4 + 1];    //G
            pixels[i * 3 + 2] = temp[i * 4];       //R

        }

        return pixels;
    }
}
